﻿using System;
using System.Collections;
using System.Data;
using System.Web;
using BEGDC.CC.BL.Common;
using BEGDC.CC.BL.UserManagement;
using BEGDC.CC.BL.Workflow;
using BEGDC.CC.Entity;
using BEGDC.Utility.Castle;
using BEGDC.Utility.ExceptionManagement;
using Castle.Facilities.NHibernateIntegration;
using Castle.Services.Transaction;
using NHibernate;

namespace BEGDC.CC.BL.CCFlow.OCV
{
    /// <summary>
    /// Summary description for CVService.
    /// </summary>
    [Transactional]
    public class OCVService : IOCV
    {
        private ISessionManager _sessionManager;
        private OCVFlow _flowInstance;

        public OCVService(ISessionManager sessionManager)
        {
            this._sessionManager = sessionManager;
        }

        public OCVService()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public FlowBase GetFlowInstance
        {
            get
            {
                if (_flowInstance == null)
                    _flowInstance = new OCVFlow();
                return _flowInstance;
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void Request(Application app, Employee lvApprover)
        {
            if (app == null) return;

            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    bool isReject = false;
                    app.AppNo = this.GenerateAppNo(false, app, true);
                    app.RequestDate = System.DateTime.Now;
                    session.Update(app);

                    FlowInstance flowinstance = this.GetFlowInstance.GetApplicationFlow(session, app.Id);
                    if (flowinstance == null)
                    {
                        flowinstance = new BEGDC.CC.Entity.FlowInstance();
                        flowinstance.FlowID = this.GetFlowInstance.Start();
                        this.GetFlowInstance.SaveFlowInstance(session, app, flowinstance, SysDicItem.ProjectStatusFlag.NORMAL, WorkTransition.OCV_Apply, WorkTransition.OCV_Apply);
                        this.GetFlowInstance.InitializeProjectMember(session, app.Id);
                    }
                    else
                    {
                        if (flowinstance.State.StateCode == SysDicItem.ProjectStatusFlag.Reject || flowinstance.State.StateCode == SysDicItem.ProjectStatusFlag.CALLBACK)
                        {
                            isReject = true;
                        }
                        this.GetFlowInstance.SaveFlowInstance(session, app, flowinstance, SysDicItem.ProjectStatusFlag.NORMAL, WorkTransition.OCV_Apply, WorkTransition.OCV_Apply);
                    }

                    IUtility utiService = AppContainer.Instance[ServiceConst.UtilityService] as IUtility;
                    int typeId = utiService.GetDicItemID(app.ApplicationType, BEGDC.CC.BL.Common.DicType.Application_Type);
                    int stepId;

                    string CostCenterHead = string.Empty;
                    string DepartmentFNC = string.Empty;
                    //string SSMEHead = string.Empty;
                    FlowMember member;

                    if (app.IsSSME)
                    {
                        CostCenterHead = this.GetFlowInstance.GetCostCenterHeadByCostCenter(session, app.CostCenterCode.DicItemKey);
                        //SSMEHead = this.GetFlowInstance.GetSSMEHead(session);
                    }
                    else
                    {
                        DepartmentFNC = this.GetFlowInstance.GetDepartmentFNCByDepartment(session, app.DepartmentType.DicItemKey);
                    }

                    if (CostCenterHead != string.Empty)
                    {
                        stepId = utiService.QueryStepByCode(WorkTransition.OCV_CostCenterHeadApproval, typeId).Id;
                        member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
                        if (member != null)
                        {
                            member.Employee = new Employee();
                            member.Employee.Id = CostCenterHead;
                            session.Update(member, member.Id);
                        }
                    }

                    if (DepartmentFNC != string.Empty)
                    {
                        stepId = utiService.QueryStepByCode(WorkTransition.OCV_DepartmentFNCApproval, typeId).Id;
                        member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
                        if (member != null)
                        {
                            member.Employee = new Employee();
                            member.Employee.Id = DepartmentFNC;
                            session.Update(member, member.Id);
                        }
                    }

                    //if (SSMEHead != string.Empty)
                    //{
                    //    stepId = utiService.QueryStepByCode(WorkTransition.OCV_SSMEEVPApproval, typeId).Id;
                    //    member = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, stepId);
                    //    if (member != null)
                    //    {
                    //        member.Employee = new Employee();
                    //        member.Employee.Id = SSMEHead;
                    //        session.Update(member, member.Id);
                    //    }
                    //}

                    //Init Lv4 Approver
                    InitWorkFlowNextLvApprover(session, app.Id, lvApprover, WorkTransition.OCV_Lv4Approval);

                    if (!isReject)
                    {
                        this.SetAssignToReportToEmployee(session, app);
                    }

                    PerformWorkflow(flowinstance.FlowID, BEGDC.CC.BL.Workflow.WorkTransition.Submit, string.Empty);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        //Get next LvApprover
        private void InitWorkFlowNextLvApprover(ISession session, int appID, Employee lvApprover, string stepName)
        {
            FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, appID, stepName, FlowTypes.OCV);
            if (member != null && lvApprover != null)
            {
                member.Employee = new Employee();
                member.Employee.Id = lvApprover.Id;
                session.Update(member, member.Id);
            }
        }

        private Nullables.NullableDateTime GetAppRequestDate(int appID)
        {

            BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
            return queryService.GetAppRequestDate(appID);

        }

        [Transaction(TransactionMode.Requires)]
        public void Save(Application app, CustomerInfo customer, BusinessPurpose business, Topic topic, SalesTeamInfo salesInfo,
            LogisticalInfo logist, PaymentInfo payment, IList customerAttendee, IList alAttendee, IList sites, IList cost, IList contract)
        {
            if (app == null) return;

            if (app.Id > 0)
            {
                if (app.RequestDate == Nullables.NullableDateTime.Default)
                {
                    Nullables.NullableDateTime date = GetAppRequestDate(app.Id);

                    if (date != Nullables.NullableDateTime.Default)
                    {
                        app.RequestDate = date;
                    }
                }
            }
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    app.AppNo = this.GenerateAppNo(true, app, false);
                    if (app.Id > 0)
                    {



                        session.Update(app);
                        customer.Application = app;
                        business.Application = app;
                        topic.Application = app;
                        salesInfo.Application = app;
                        logist.Application = app;
                        payment.Application = app;
                        session.Update(customer);
                        session.Update(business);
                        session.Update(topic);
                        session.Update(salesInfo);
                        session.Update(logist);
                        session.Update(payment);

                        session.Delete("from CustomerAttendee where CustomerInfoID=" + customer.Id);
                        for (int i = 0; i < customerAttendee.Count; i++)
                        {
                            CustomerAttendee cus = (CustomerAttendee)customerAttendee[i];
                            cus.CustomerInfo = customer;
                            session.Save(cus);
                        }
                        session.Delete("from ALAttendee where AppID=" + app.Id);
                        for (int i = 0; i < alAttendee.Count; i++)
                        {
                            ALAttendee al = (ALAttendee)alAttendee[i];
                            al.Application = app;
                            session.Save(al);
                        }
                        session.Delete("from AppVisitingSite where AppID=" + app.Id);
                        for (int i = 0; i < sites.Count; i++)
                        {
                            AppVisitingSite site = (AppVisitingSite)sites[i];
                            site.Application = app;
                            session.Save(site);
                        }
                        session.Delete("from CostCenterRelatedCost where PaymentInfoID=" + payment.Id);//+" and costtype="+CostType.Budget);
                        for (int i = 0; i < cost.Count; i++)
                        {
                            CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
                            co.PaymentInfo = payment;
                            session.Save(co);
                        }
                        session.Delete("from ContractInfo where AppID=" + app.Id);
                        for (int i = 0; i < contract.Count; i++)
                        {
                            ContractInfo ci = (ContractInfo)contract[i];
                            ci.Application = app;
                            session.Save(ci);
                        }
                    }
                    else
                    {
                        session.Save(app);
                        customer.Application = app;
                        business.Application = app;
                        topic.Application = app;
                        salesInfo.Application = app;
                        logist.Application = app;
                        payment.Application = app;
                        session.Save(customer);
                        session.Save(business);
                        session.Save(topic);
                        session.Save(salesInfo);
                        session.Save(logist);
                        session.Save(payment);

                        for (int i = 0; i < customerAttendee.Count; i++)
                        {
                            CustomerAttendee cus = (CustomerAttendee)customerAttendee[i];
                            cus.CustomerInfo = customer;
                            session.Save(cus);
                        }
                        for (int i = 0; i < alAttendee.Count; i++)
                        {
                            ALAttendee al = (ALAttendee)alAttendee[i];
                            al.Application = app;
                            session.Save(al);
                        }
                        for (int i = 0; i < sites.Count; i++)
                        {
                            AppVisitingSite site = (AppVisitingSite)sites[i];
                            site.Application = app;
                            session.Save(site);
                        }
                        for (int i = 0; i < cost.Count; i++)
                        {
                            CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
                            co.PaymentInfo = payment;
                            session.Save(co);
                        }
                        for (int i = 0; i < contract.Count; i++)
                        {
                            ContractInfo ci = (ContractInfo)contract[i];
                            ci.Application = app;
                            session.Save(ci);
                        }
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void Assign(long flowID, string nextTransition, string employeeNo, int appID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                if (nextTransition == CVTransitionList.Assign)
                {
                    FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, appID, WorkTransition.OCV_Check, FlowTypes.OCV);
                    member.Employee = new Employee();
                    member.Employee.Id = employeeNo;
                    session.Update(member, member.Id);

                    member = this.GetFlowInstance.GetFlowMemberByAppStep(session, appID, WorkTransition.OCV_Close, FlowTypes.OCV);
                    member.Employee = new Employee();
                    member.Employee.Id = employeeNo;
                    session.Update(member, member.Id);
                }
                PerformWorkflow(flowID, nextTransition, comment);
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void Check(long flowID, string nextTransition, string comment)
        {
            FlowInstance instance = new FlowInstance();
            using (ISession session = _sessionManager.OpenSession())
            {
                instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);

                if (instance.CurrentStep.StepName == WorkTransition.OCV_Assignment)
                {
                    if (nextTransition == OCVTransitionList.Check)
                    {
                        FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.OCV_Check, FlowTypes.OCV);
                        member.Employee = new Employee();
                        member.Employee.Id = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.Id;
                        session.Update(member, member.Id);

                        member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.OCV_Close, FlowTypes.OCV);
                        member.Employee = new Employee();
                        member.Employee.Id = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.Id;
                        session.Update(member, member.Id);
                    }
                }
            }

            PerformWorkflow(flowID, nextTransition, comment);

            if (instance.FlowID > 0)
            {
                this.CostCenterAutomaticallyApprove(instance);
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void ReAssign(long flowID, string employeeNo)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);

                FlowMember member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.OCV_Check, FlowTypes.OCV);
                if (member.Employee != null)
                {
                    if (member.Employee.Id == instance.CurrentActiveOwner)
                        instance.CurrentActiveOwner = employeeNo;
                    if (member.Employee.Id == instance.CurrentOwner)
                        instance.CurrentOwner = employeeNo;
                    session.Update(instance, instance.Id);
                }
                member.Employee = new Employee();
                member.Employee.Id = employeeNo;
                session.Update(member, member.Id);

                member = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.OCV_Close, FlowTypes.OCV);
                member.Employee = new Employee();
                member.Employee.Id = employeeNo;
                session.Update(member, member.Id);
                this.GetFlowInstance.SaveActionLog(session, instance.Application.Id, BEGDC.CC.BL.Workflow.Action.Reassign, instance.CurrentStep.StepCode, instance.CurrentStep.StepCode, string.Empty);
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void DepartmentVPApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void SSMEEVPApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void SubmitLVLeadApproval(long flowID, int appID, string nextTransition, Employee nextLvApprover, string stepName, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    if (nextLvApprover != null)
                    {
                        // stepName is current step, need next step actor
                        switch (stepName)
                        {
                            case WorkTransition.OCV_Lv4Approval:
                                stepName = WorkTransition.OCV_Lv3Approval;
                                break;
                            case WorkTransition.OCV_Lv3Approval:
                                stepName = WorkTransition.OCV_Lv2Approval;
                                break;
                            case WorkTransition.OCV_Lv2Approval:
                                stepName = WorkTransition.OCV_Lv1Approval;
                                break;
                            default:
                                stepName = string.Empty;
                                break;
                        }
                        this.InitWorkFlowNextLvApprover(session, appID, nextLvApprover, stepName);
                    }
                    this.GetFlowInstance.Perform(session, flowID, nextTransition, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void CostCenterHeadApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);

            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);

                    if (instance != null && instance.FlowID > 0)
                    {
                        this.Lv4ApproverAutomaticallyApprove(session, instance, instance.Application);
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void DepartmentHeadApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
            //this.IBGHeaderIsReportTo(flowID);
        }

        [Transaction(TransactionMode.Requires)]
        public void DepartmentFNCApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void CODApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void CODVPApprove(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void Summary(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void Close(long flowID, string nextTransition, string comment)
        {
            PerformWorkflow(flowID, nextTransition, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void DrawBack(long flowID, string comment)
        {
            this.GetFlowInstance.Drawback(_sessionManager.OpenSession(), flowID, comment);
        }

        [Transaction(TransactionMode.Requires)]
        public void Query(long flowID, string activeStep, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Query(session, flowID, activeStep, SysDicItem.ProjectStatusFlag.QUERY, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void ReplyQuery(long flowID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.ReplyInquiry(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Suspend(long flowID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Suspend(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Archive(long flowID)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Archive(session, flowID);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Resume(long flowID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Resume(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        private void PerformWorkflow(long flowID, string nextTransition, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Perform(_sessionManager.OpenSession(), flowID, nextTransition, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        #region Survey
        [Transaction(TransactionMode.Requires)]
        public void SubmitSurvey(Application App, BEGDC.CC.Entity.CustomerSurvey survey, IList AnswerList)
        {
            if (App == null) return;

            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    if (survey != null)
                    {
                        if (survey.Id != 0)
                        {
                            session.Update(survey);
                        }
                        else
                        {
                            session.Save(survey);
                        }
                    }

                    for (int i = 0; i < AnswerList.Count; i++)
                    {
                        BEGDC.CC.Entity.SurveyAnswer sa = AnswerList[i] as BEGDC.CC.Entity.SurveyAnswer;
                        sa.CustomerSurvey = survey;
                        if (sa.Id != 0)
                        {
                            session.Update(sa);
                        }
                        else
                        {
                            session.Save(sa);
                        }
                    }

                    BEGDC.CC.Entity.FlowInstance flowinstance = this.GetFlowInstance.GetApplicationFlow(session, App.Id);
                    this.GetFlowInstance.Perform(session, flowinstance.FlowID, BEGDC.CC.BL.Workflow.WorkTransition.Submit, string.Empty);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public void SaveSurvey(Application App, BEGDC.CC.Entity.CustomerSurvey survey, IList AnswerList)
        {
            if (App == null) return;

            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    if (survey != null)
                    {
                        if (survey.Id != 0)
                        {
                            session.Update(survey);
                        }
                        else
                        {
                            session.Save(survey);
                        }
                    }

                    for (int i = 0; i < AnswerList.Count; i++)
                    {
                        BEGDC.CC.Entity.SurveyAnswer sa = AnswerList[i] as BEGDC.CC.Entity.SurveyAnswer;
                        sa.CustomerSurvey = survey;
                        if (sa.Id != 0)
                        {
                            session.Update(sa);
                        }
                        else
                        {
                            session.Save(sa);
                        }
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion
        private string GenerateAppNo(bool isSave, Application app, bool isRequest)
        {
            int maxId;
            string year = string.Empty;
            if (app.AppNo != string.Empty)
            {
                string temp = app.AppNo;
                temp = temp.Replace("-D", string.Empty);
                BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
                //if (isRequest)
                //{
                //    maxId = queryService.GetMaxAppID(WorkflowTypes.OCV, isSave && (app.AppNo.IndexOf("-D") > 0 || app.AppNo == string.Empty));
                //    year = DateTime.Now.Year.ToString().Substring(2);
                //}
                //else
                //{
                //    year = temp.Substring(temp.Length - 7, 2);
                //    maxId = Convert.ToInt32(temp.Substring(temp.Length - 4));
                //}
                year = temp.Substring(temp.Length - 7, 2);
                maxId = Convert.ToInt32(temp.Substring(temp.Length - 4));
            }
            else
            {
                BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
                maxId = queryService.GetMaxAppID(WorkflowTypes.OCV, isSave && (app.AppNo.IndexOf("-D") > 0 || app.AppNo == string.Empty));
                year = DateTime.Now.Year.ToString().Substring(2);
            }

            string AppNo = "";
            if (app.CostCenterCode != null && app.CostCenterCode.DicItemKey != string.Empty)
            {
                AppNo += app.CostCenterCode.DicItemKey + "-";
            }
            else
            {
                AppNo += app.DepartmentType.DicItemKey + "-";
            }
            AppNo += year + "-" + maxId.ToString().PadLeft(4, '0');
            AppNo = "IBGCV-" + AppNo;
            if (isSave && (app.AppNo.IndexOf("-D") > 0 || app.AppNo == string.Empty))
                AppNo += "-D";
            return AppNo;

        }

        public void Callback(long flowID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Callback(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        public void Cancel(long flowID, string comment)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    this.GetFlowInstance.Cancel(session, flowID, comment);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void SaveCloseApp(Application App, IList cost, int paymentId)
        {
            if (App == null) return;

            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    if (App.Id > 0)
                    {
                        session.Update(App);
                        session.Delete("from CostCenterRelatedCost where PaymentInfoID=" + paymentId);
                        for (int i = 0; i < cost.Count; i++)
                        {
                            CostCenterRelatedCost co = (CostCenterRelatedCost)cost[i];
                            session.Save(co);
                        }
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        [Transaction(TransactionMode.Requires)]
        public void CopyOCV(int appId)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {

                    //GET APPLICATION-------------------------------------------------------------------------------
                    Application app = session.Get(typeof(Application), appId) as Application;
                    if (app == null)
                        return;

                    //CREATE NEW APPLICATION
                    #region New App
                    Application newapp = new Application();
                    newapp.RequesterNo = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo;
                    newapp.Account = app.Account;
                    newapp.AllDept = app.AllDept;
                    newapp.Activity = app.Activity;
                    newapp.AlternateDateFrom = app.AlternateDateFrom;
                    newapp.AlternateDateTo = app.AlternateDateTo;
                    newapp.ApplicationType = app.ApplicationType;
                    newapp.ApplyForSomeoneElse = app.ApplyForSomeoneElse;
                    newapp.CATBranch = app.CATBranch;
                    newapp.DepartmentName = app.DepartmentName;
                    newapp.DepartmentType = app.DepartmentType;
                    newapp.IsReviewedGuideline = app.IsReviewedGuideline;
                    newapp.IsTransition = app.IsTransition;
                    newapp.LGDNo = app.LGDNo;
                    newapp.OtherCountry = app.OtherCountry;
                    newapp.Others = app.Others;
                    newapp.OtherSite = app.OtherSite;
                    newapp.RequestDate = System.DateTime.Now;
                    newapp.RequestedDateFrom = app.RequestedDateFrom;
                    newapp.RequestedDateTo = app.RequestedDateTo;
                    newapp.RequesterDept = app.RequesterDept;
                    newapp.RequesterMobile = app.RequesterMobile;
                    newapp.RequesterNameCN = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.NameCN;
                    newapp.RequesterNameEN = ((CCIdentity)HttpContext.Current.User.Identity).UserInfo.NameEN;
                    newapp.RequesterOfficeTel = app.RequesterOfficeTel;
                    newapp.SomeoneElseEmail = app.SomeoneElseEmail;
                    newapp.SomeoneElseHRID = app.SomeoneElseHRID;
                    newapp.SomeoneElseMobil = app.SomeoneElseMobil;
                    newapp.SomeoneElseNameCN = app.SomeoneElseNameCN;
                    newapp.SomeoneElseNameEN = app.SomeoneElseNameEN;
                    newapp.SomeoneElseNo = app.SomeoneElseNo;
                    newapp.SomeoneElseTel = app.SomeoneElseTel;
                    newapp.Summary = app.Summary;
                    newapp.LegalEntity = app.LegalEntity;
                    newapp.AppNo = string.Empty;

                    newapp.IsSSME = app.IsSSME;
                    newapp.BUHeadApproved = app.BUHeadApproved;
                    newapp.CostCenterCode = app.CostCenterCode;
                    newapp.NeedEVPApproval = false;
                    newapp.AppNo = this.GenerateAppNo(true, newapp, false);

                    session.Save(newapp);
                    #endregion

                    //CREATE NEW CUSTOMER
                    #region New Customer
                    IList CustomerList = session.Find("From CustomerInfo WHERE AppID = " + appId);
                    Entity.CustomerInfo customer = null;
                    if (CustomerList != null && CustomerList.Count > 0)
                    {
                        customer = CustomerList[0] as CustomerInfo;
                    }
                    CustomerInfo newcustomer = null;
                    if (customer != null)
                    {
                        newcustomer = new CustomerInfo();
                        newcustomer.Application = newapp;
                        newcustomer.AccountType = customer.AccountType;
                        newcustomer.CompanyProfile = customer.CompanyProfile;
                        newcustomer.Company = customer.Company;
                        newcustomer.Venue = customer.Venue;
                        newcustomer.VisitObjective = customer.VisitObjective;
                        newcustomer.Country = customer.Country;
                        newcustomer.IsFCPA = customer.IsFCPA;
                        newcustomer.IsInRFP = customer.IsInRFP;
                        newcustomer.IsInRFP = customer.IsInRFP;

                        newcustomer.IsKeyMessage = customer.IsKeyMessage;
                        newcustomer.IsSensitiveIssue = customer.IsSensitiveIssue;
                        newcustomer.IsThereSensitiveIssue = customer.IsThereSensitiveIssue;
                        newcustomer.IsThereKeyMessage = customer.IsThereKeyMessage;
                        newcustomer.Name = customer.Name;
                        newcustomer.NumberOfPerson = customer.NumberOfPerson;
                        newcustomer.PotentialRevenueTimeframe = customer.PotentialRevenueTimeframe;
                        newcustomer.ProposalNo = customer.ProposalNo;
                        newcustomer.RevenuePotential = customer.RevenuePotential;

                        newcustomer.RFPDetail = customer.RFPDetail;
                        newcustomer.SalesStage = customer.SalesStage;
                        newcustomer.Title = customer.Title;
                        newcustomer.Venue = customer.Venue;
                        newcustomer.VisitObjective = customer.VisitObjective;
                        session.Save(newcustomer);
                    }
                    #endregion

                    //CREATE NEW BUSINESS
                    #region New Business
                    IList BusinessList = session.Find("From BusinessPurpose WHERE AppID = " + appId);
                    Entity.BusinessPurpose business = null;
                    if (BusinessList != null && BusinessList.Count > 0)
                    {
                        business = BusinessList[0] as BusinessPurpose;
                    }
                    Entity.BusinessPurpose newbusiness = null;
                    if (business != null)
                    {
                        newbusiness = new BusinessPurpose();
                        newbusiness.Application = newapp;
                        newbusiness.IsContractSigned = business.IsContractSigned;
                        newbusiness.IsInSalesContract = business.IsInSalesContract;
                        newbusiness.IsNeedInvitationLetter = business.IsNeedInvitationLetter;
                        newbusiness.Itinerary = business.Itinerary;
                        newbusiness.Opportunities = business.Opportunities;
                        newbusiness.RecreationalActivity = business.RecreationalActivity;
                        session.Save(newbusiness);
                    }
                    #endregion

                    //CREATE NEW SALES
                    #region New Sales
                    IList SalesList = session.Find("From SalesTeamInfo WHERE AppID = " + appId);
                    Entity.SalesTeamInfo sales = null;
                    if (SalesList != null && SalesList.Count > 0)
                    {
                        sales = SalesList[0] as SalesTeamInfo;
                    }
                    Entity.SalesTeamInfo newsales = null;
                    if (sales != null)
                    {
                        newsales = new SalesTeamInfo();
                        newsales.Application = newapp;
                        newsales.Email = sales.Email;
                        newsales.HostNameCN = sales.HostNameCN;
                        newsales.HostNameEN = sales.HostNameEN;
                        newsales.OfficeFax = sales.OfficeFax;
                        newsales.OfficeTel = sales.OfficeTel;
                        newsales.Region = sales.Region;
                        newsales.SalesBusinessUnit = sales.SalesBusinessUnit;
                        session.Save(newsales);
                    }
                    #endregion

                    //CREATE NEW TOPIC
                    #region New Topic
                    IList TopicList = session.Find("From Topic WHERE AppID = " + appId);
                    Entity.Topic topic = null;
                    if (TopicList != null && TopicList.Count > 0)
                    {
                        topic = TopicList[0] as Topic;
                    }
                    Entity.Topic newtopic = null;
                    if (topic != null)
                    {
                        newtopic = new Topic();
                        newtopic.Application = newapp;
                        newtopic.TopicName = topic.TopicName;
                        session.Save(newtopic);
                    }
                    #endregion

                    //CREATE NEW LOGISTIC
                    #region New Logistic
                    IList LogisticalList = session.Find("From LogisticalInfo WHERE AppID = " + appId);
                    Entity.LogisticalInfo logistic = null;
                    if (LogisticalList != null && LogisticalList.Count > 0)
                    {
                        logistic = LogisticalList[0] as LogisticalInfo;
                    }
                    Entity.LogisticalInfo newlogistic = null;
                    if (logistic != null)
                    {
                        newlogistic = new LogisticalInfo();
                        newlogistic.Application = newapp;
                        newlogistic.ArrivalAirport = logistic.ArrivalAirport;
                        newlogistic.ArrivalFlightNo = logistic.ArrivalFlightNo;
                        newlogistic.ArrivalTime = logistic.ArrivalTime;
                        newlogistic.AverageMealCost = logistic.AverageMealCost;
                        newlogistic.CateringDescription = logistic.CateringDescription;
                        newlogistic.Comment = logistic.Comment;
                        newlogistic.DateRequiredFrom = logistic.DateRequiredFrom;
                        newlogistic.DateRequiredTo = logistic.DateRequiredTo;
                        newlogistic.DecryptedEntertainmentPriceFrom = logistic.DecryptedEntertainmentPriceFrom;
                        newlogistic.DecryptedEntertainmentPriceTo = logistic.DecryptedEntertainmentPriceTo;
                        newlogistic.DecryptedGiftPriceFrom = logistic.DecryptedGiftPriceFrom;
                        newlogistic.DecryptedGiftPriceTo = logistic.DecryptedGiftPriceTo;
                        newlogistic.DecryptedPriceFrom = logistic.DecryptedPriceFrom;
                        newlogistic.DecryptedPriceTo = logistic.DecryptedPriceTo;
                        newlogistic.DepartureAirport = logistic.DepartureAirport;
                        newlogistic.DepartureFlightNo = logistic.DepartureFlightNo;
                        newlogistic.DepartureTime = logistic.DepartureTime;
                        newlogistic.Duration = logistic.Duration;
                        newlogistic.EntertainmentPreference = logistic.EntertainmentPreference;

                        newlogistic.GiftDetails = logistic.GiftDetails;
                        newlogistic.GiftPreference = logistic.GiftPreference;
                        newlogistic.HotelPreferences = logistic.HotelPreferences;
                        newlogistic.InterpretionType = logistic.InterpretionType;
                        newlogistic.IsMealReservation = logistic.IsMealReservation;
                        newlogistic.IsNeedCatering = logistic.IsNeedCatering;
                        newlogistic.IsNeedEntertainment = logistic.IsNeedEntertainment;
                        newlogistic.IsNeedGift = logistic.IsNeedGift;
                        newlogistic.IsNeedGroundTransportation = logistic.IsNeedGroundTransportation;
                        newlogistic.IsNeedHotel = logistic.IsNeedHotel;
                        newlogistic.IsNeedInterpreter = logistic.IsNeedInterpreter;
                        newlogistic.IsNeedTravelAgency = logistic.IsNeedTravelAgency;
                        newlogistic.IsReceivedALGiftBefore = logistic.IsReceivedALGiftBefore;
                        newlogistic.Itinerary = logistic.Itinerary;
                        newlogistic.MealReservation = logistic.MealReservation;
                        newlogistic.MeetingRoom = logistic.MeetingRoom;
                        newlogistic.ReceivedGiftDetails = logistic.ReceivedGiftDetails;
                        newlogistic.SpecialDialect = logistic.SpecialDialect;
                        newlogistic.TravelAgency = logistic.TravelAgency;
                        session.Save(newlogistic);
                    }
                    #endregion

                    //CREATE NEW PAYMENT
                    #region New Payment
                    IList PaymentList = session.Find("From PaymentInfo WHERE AppID = " + appId);
                    Entity.PaymentInfo payment = null;
                    if (PaymentList != null && PaymentList.Count > 0)
                    {
                        payment = PaymentList[0] as PaymentInfo;
                    }
                    Entity.PaymentInfo newpayment = null;
                    if (payment != null)
                    {
                        newpayment = new PaymentInfo();
                        newpayment.Application = newapp;
                        newpayment.Comments = payment.Comments;
                        newpayment.CustomerPerdiem = payment.CustomerPerdiem;
                        newpayment.DecryptedEstimateCustomerdIndividualCost = payment.DecryptedEstimateCustomerdIndividualCost;
                        newpayment.DecryptedEstimatedCustomerTotalCost = payment.DecryptedEstimatedCustomerTotalCost;
                        newpayment.EstimateCustomerdIndividualCost = payment.EstimateCustomerdIndividualCost;
                        newpayment.EstimatedCustomerTotalCost = payment.EstimatedCustomerTotalCost;
                        newpayment.IsPayServiceProvider = payment.IsPayServiceProvider;
                        newpayment.NotDirectPayReasons = payment.NotDirectPayReasons;
                        newpayment.Payer = payment.Payer;
                        session.Save(newpayment);
                    }
                    #endregion

                    #region Customer List
                    IList CustomerAttendeeList = null;
                    if (customer != null && newcustomer != null)
                    {
                        CustomerAttendeeList = session.Find("FROM CustomerAttendee WHERE CustomerInfoID = " + customer.Id);
                        if (CustomerAttendeeList != null && CustomerAttendeeList.Count > 0)
                        {
                            for (int i = 0; i < CustomerAttendeeList.Count; i++)
                            {
                                Entity.CustomerAttendee att = CustomerAttendeeList[i] as Entity.CustomerAttendee;
                                if (att != null)
                                {
                                    Entity.CustomerAttendee newatt = new Entity.CustomerAttendee();
                                    newatt.CustomerInfo = newcustomer;
                                    newatt.Affects = att.Affects;
                                    newatt.ClearDate = att.ClearDate;
                                    newatt.Company = att.Company;
                                    newatt.CompanyEN = att.CompanyEN;
                                    newatt.Gender = att.Gender;
                                    newatt.IsAttended = att.IsAttended;
                                    newatt.IsExisted = att.IsExisted;
                                    newatt.NameCN = att.NameCN;
                                    newatt.NameEN = att.NameEN;
                                    newatt.Remark = att.Remark;
                                    newatt.Responsibility = att.Responsibility;
                                    newatt.Title = att.Title;
                                    newatt.TitleEN = att.TitleEN;
                                    session.Save(newatt);
                                }
                            }
                        }
                    }
                    #endregion

                    #region AL Attendee
                    //Get AL Attendee list
                    IList alAttendeeList = session.Find("From ALAttendee WHERE AppID = " + appId);
                    if (alAttendeeList != null && alAttendeeList.Count > 0)
                    {
                        for (int i = 0; i < alAttendeeList.Count; i++)
                        {
                            Entity.ALAttendee attendee = alAttendeeList[i] as Entity.ALAttendee;
                            if (attendee != null)
                            {
                                Entity.ALAttendee newalattendee = new Entity.ALAttendee();
                                newalattendee.Application = newapp;
                                newalattendee.ContactInfo = attendee.ContactInfo;
                                newalattendee.EmployeeId = attendee.EmployeeId;
                                newalattendee.Title = attendee.Title;
                                session.Save(newalattendee);
                            }
                        }
                    }
                    #endregion

                    #region App Visiting Site
                    //Get AL Attendee list
                    IList VisitingSiteList = session.Find("from AppVisitingSite where AppID=" + appId);
                    if (VisitingSiteList != null && VisitingSiteList.Count > 0)
                    {
                        for (int i = 0; i < VisitingSiteList.Count; i++)
                        {
                            Entity.AppVisitingSite site = VisitingSiteList[i] as Entity.AppVisitingSite;
                            if (site != null)
                            {
                                Entity.AppVisitingSite newsite = new Entity.AppVisitingSite();
                                newsite.Application = newapp;
                                newsite.Site = site.Site;
                                session.Save(newsite);
                            }
                        }
                    }
                    #endregion

                    #region Cost Center Related Cost
                    //Get AL Attendee list
                    if (payment != null && newpayment != null)
                    {
                        IList CostList = session.Find("from CostCenterRelatedCost where PaymentInfoID=" + payment.Id);
                        if (CostList != null && CostList.Count > 0)
                        {
                            for (int i = 0; i < CostList.Count; i++)
                            {
                                Entity.CostCenterRelatedCost cost = CostList[i] as Entity.CostCenterRelatedCost;
                                if (cost != null)
                                {
                                    Entity.CostCenterRelatedCost newcost = new Entity.CostCenterRelatedCost();
                                    newcost.PaymentInfo = newpayment;
                                    newcost.Cost = cost.Cost;
                                    newcost.CostCenterCode = cost.CostCenterCode;
                                    newcost.CostType = cost.CostType;
                                    newcost.DecryptedCost = cost.DecryptedCost;
                                    session.Save(newcost);
                                }
                            }
                        }
                    }
                    #endregion

                    #region Contract
                    IList ContractList = session.Find("from ContractInfo where AppID=" + appId);
                    if (ContractList != null && ContractList.Count > 0)
                    {
                        for (int i = 0; i < ContractList.Count; i++)
                        {
                            Entity.ContractInfo contract = ContractList[i] as Entity.ContractInfo;
                            if (contract != null)
                            {
                                Entity.ContractInfo newcontract = new Entity.ContractInfo();
                                newcontract.Application = newapp;
                                newcontract.Budget = contract.Budget;
                                newcontract.ContractNo = contract.ContractNo;
                                newcontract.DateOfContract = contract.DateOfContract;
                                newcontract.ProducstSold = contract.ProducstSold;
                                newcontract.Quotas = contract.Quotas;
                                newcontract.UnitPrice = contract.UnitPrice;
                                newcontract.VisitPurposeInContract = contract.VisitPurposeInContract;
                                session.Save(newcontract);
                            }
                        }
                    }
                    #endregion

                    #region Attachment
                    //Get Attachments					
                    IList attList = session.Find(" From Attachment WHERE AppID = " + appId);
                    if (attList != null && attList.Count > 0)
                    {
                        for (int i = 0; i < attList.Count; i++)
                        {
                            Entity.Attachment att = attList[i] as Attachment;
                            if (att != null)
                            {
                                Entity.Attachment newatt = new Entity.Attachment();
                                newatt.Application = newapp;
                                newatt.ActionPoint = att.ActionPoint;
                                newatt.AttachmentType = att.AttachmentType;
                                newatt.Date = att.Date;
                                newatt.FileName = att.FileName;
                                newatt.FilePath = att.FilePath;
                                newatt.Owner = att.Owner;
                                session.Save(newatt);
                            }
                        }
                    }
                    #endregion

                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message);
                    throw new GDCException(ErrorCode.DB_Exception, ex.Message, ex);
                }
                finally
                {
                    session.Close();
                }
            }
        }

        private void ConvertDatatableToList(DataTable dtSite, DataTable dtCustomer, DataTable dtAL, DataTable dtCost,
            DataTable dtContract, ref IList customerAttendee, ref IList alAttendee, ref IList site, ref IList cost, ref IList contract)
        {
            // site info
            if (dtSite != null && dtSite.Rows.Count > 0)
            {
                for (int i = 0; i < dtSite.Rows.Count; i++)
                {
                    AppVisitingSite appSite = new AppVisitingSite();
                    appSite.Site = new DicItem();
                    appSite.Site.Id = Convert.ToInt32(dtSite.Rows[i]["DicItemID"]);

                    site.Add(appSite);
                }
            }

            // Customer Attendee Info
            if (dtCustomer != null && dtCustomer.Rows.Count > 0)
            {
                for (int i = 0; i < dtCustomer.Rows.Count; i++)
                {
                    CustomerAttendee cus = new CustomerAttendee();
                    cus.NameEN = dtCustomer.Rows[i]["Name"].ToString();
                    cus.Title = dtCustomer.Rows[i]["Title"].ToString();
                    cus.Responsibility = new DicItem();
                    cus.Responsibility.Id = Convert.ToInt32(dtCustomer.Rows[i]["ResponsibilityID"]);
                    cus.Affects = new DicItem();
                    cus.Affects.Id = Convert.ToInt32(dtCustomer.Rows[i]["AffectsID"]);
                    cus.IsAttended = true;
                    cus.Remark = dtCustomer.Rows[i]["Remark"].ToString();

                    customerAttendee.Add(cus);
                }
            }

            // AL Attendee Info
            if (dtAL != null && dtAL.Rows.Count > 0)
            {
                for (int i = 0; i < dtAL.Rows.Count; i++)
                {
                    ALAttendee al = new ALAttendee();
                    al.EmployeeId = new Employee();
                    al.EmployeeId.Id = dtAL.Rows[i]["EmployeeId"].ToString();
                    al.Title = dtAL.Rows[i]["Title"].ToString();

                    alAttendee.Add(al);
                }
            }

            // Cost Center Info
            if (dtCost != null && dtCost.Rows.Count > 0)
            {
                for (int i = 0; i < dtCost.Rows.Count; i++)
                {
                    CostCenterRelatedCost co = new CostCenterRelatedCost();
                    co.CostCenterCode = dtCost.Rows[i]["CostCenterCode"].ToString();
                    co.DecryptedCost = Convert.ToDecimal(dtCost.Rows[i]["Cost"]);
                    co.CostType = CostType.Budget;

                    cost.Add(co);
                }
            }

            // Contract Info
            if (dtContract != null && dtContract.Rows.Count > 0)
            {
                for (int i = 0; i < dtContract.Rows.Count; i++)
                {
                    ContractInfo ci = new ContractInfo();
                    ci.DateOfContract = Convert.ToDateTime(dtContract.Rows[i]["DateOfContract"]);
                    ci.ContractNo = dtContract.Rows[i]["ContractNo"].ToString();
                    ci.ProducstSold = dtContract.Rows[i]["ProducstSold"].ToString();
                    ci.VisitPurposeInContract = dtContract.Rows[i]["VisitPurposeInContract"].ToString();
                    ci.Quotas = Convert.ToInt32(dtContract.Rows[i]["Quotas"]);
                    ci.UnitPrice = Convert.ToDecimal(dtContract.Rows[i]["UnitPrice"]);
                    ci.Budget = Convert.ToDecimal(dtContract.Rows[i]["Budget"]);

                    contract.Add(ci);
                }
            }

        }

        #region Get Infomation
        [Transaction(TransactionMode.Requires)]
        public BEGDC.CC.Entity.Application GetApplication(int AppID)
        {
            IList list;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    list = session.Find("From Application as app where app.Id=" + AppID);
                    if (list.Count > 0)
                    {
                        BEGDC.CC.Entity.Application App = list[0] as BEGDC.CC.Entity.Application;
                        return App;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public BEGDC.CC.Entity.CustomerSurvey GetCustomerSurvey(int AppID)
        {
            IList CtInfo = null;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    CtInfo = session.Find("From CustomerSurvey as cs where cs.Application.Id=" + AppID);
                    if (CtInfo != null && CtInfo.Count > 0)
                    {
                        //Get Customer Info
                        BEGDC.CC.Entity.CustomerSurvey survey = CtInfo[0] as BEGDC.CC.Entity.CustomerSurvey;

                        return survey;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public BEGDC.CC.Entity.LogisticalInfo GetLogisticalInfo(int AppID)
        {
            IList list;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    list = session.Find("From LogisticalInfo as log where log.Application.Id=" + AppID);
                    if (list != null && list.Count > 0)
                    {
                        BEGDC.CC.Entity.LogisticalInfo log = list[0] as BEGDC.CC.Entity.LogisticalInfo;
                        return log;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public DataTable GetSurveyQuestions(string appType, string Type, bool Enable)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    string EnableStr = " and sq.isEnable='1' ";
                    string sql = "";
                    if (Enable)
                    {
                        sql = "Select sq.QuestionID AS Id, sq.Question AS Question, sq.Type AS Type, sq.Sort AS Sort, sq.isEnable AS Enable From SurveyQuestion AS sq where sq.Type='" + Type + "' " + EnableStr + " and applicationtype='" + appType + "'order by sq.Sort";
                    }
                    else
                    {
                        sql = "Select sq.QuestionID AS Id, sq.Question AS Question, sq.Type AS Type, sq.Sort AS Sort, sq.isEnable AS Enable From SurveyQuestion AS sq where sq.Type='" + Type + "' and applicationtype='" + appType + "' order by sq.Sort";
                    }
                    return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public DataTable GetSurveyAnswer(int SurveyId)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    string sql = "Select sa.QuestionID AS QuestionId, sa.Score AS Score, sa.Comment AS Comment From SurveyAnswer AS sa where sa.CustomerSurveyID=" + SurveyId;
                    return BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public IList GetSurveyAnswerList(int SurveyId)
        {
            IList AnswerList = null;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    AnswerList = session.Find("From SurveyAnswer as sa where sa.CustomerSurvey.Id=" + SurveyId);
                    if (AnswerList != null && AnswerList.Count > 0)
                    {
                        return AnswerList;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        [Transaction(TransactionMode.Requires)]
        public IList GetSurveyQuestionList()
        {
            IList QList = null;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    QList = session.Find("From SurveyQuestion");
                    if (QList != null && QList.Count > 0)
                    {
                        return QList;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion

        #region ReportTo Employee
        private void SetAssignToReportToEmployee(ISession session, Application app)
        {
            //if (app.CostCenterCode != null && !string.IsNullOrEmpty(app.RequesterNo.ReportTo.Id))
            //{
            //    //Get CostCenter Head
            //    BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;
            //    string costCenterHeaderID = queryService.GetCostCenterHead(session, BEGDC.CC.BL.Workflow.UserRole.CostCenterHead, app.CostCenterCode.DicItemKey);

            //    //Compare CostCenter Head != ReportTo Employee
            //    if (costCenterHeaderID != app.RequesterNo.ReportTo.Id)
            //    {
            //        FlowMember member = _flowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_Assignment, FlowTypes.OCV);
            //        member.Employee = new Employee();
            //        member.Employee.Id = app.RequesterNo.ReportTo.Id;
            //        session.Update(member, member.Id);

            //        //set reportToApprove member
            //        FlowMember memberReport = _flowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_ReportTo, FlowTypes.OCV);
            //        memberReport.Employee = new Employee();
            //        memberReport.Employee.Id = app.RequesterNo.ReportTo.Id;
            //        session.Update(memberReport, memberReport.Id);
            //    }
            //}
            if (app.RequesterNo.ReportTo != null)
            {
                FlowMember member = _flowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_Assignment, FlowTypes.OCV);
                member.Employee = new Employee();
                member.Employee.Id = app.RequesterNo.ReportTo.Id;
                session.Update(member, member.Id);

                //set reportToApprove member
                FlowMember memberReport = _flowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_ReportTo, FlowTypes.OCV);
                memberReport.Employee = new Employee();
                memberReport.Employee.Id = app.RequesterNo.ReportTo.Id;
                session.Update(memberReport, memberReport.Id);
            }
        }

        /// <summary>
        /// ReportTo Approved 
        /// </summary>
        [Transaction(TransactionMode.Requires)]
        public void ReportToEmployeeApproved(Application app)
        {
            if (app == null) return;
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    ////Clear Assign
                    //FlowMember member = _flowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_Assignment, FlowTypes.OCV);
                    //member.Employee = null;
                    //session.Update(member);

                    //Change flow step
                    BEGDC.CC.Entity.FlowInstance flowinstance = this.GetFlowInstance.GetApplicationFlow(session, app.Id);
                    this.GetFlowInstance.SaveFlowInstance(session, app, flowinstance, SysDicItem.ProjectStatusFlag.NORMAL, WorkTransition.OCV_Assignment, WorkTransition.OCV_Assignment);
                    flowinstance.CurrentOwner = BEGDC.CC.BL.Workflow.UserRole.OCVMgr;
                    flowinstance.CurrentActiveOwner = BEGDC.CC.BL.Workflow.UserRole.OCVMgr;
                    session.Update(flowinstance);

                    //Save Action log
                    string currentStep = WorkTransition.OCV_ReportTo;
                    string nextStep = WorkTransition.OCV_Assignment;
                    string nextTransition = BEGDC.CC.BL.Workflow.Action.ReportToCheck;
                    this.GetFlowInstance.SaveActionLog(session, app.Id, nextTransition, currentStep, nextStep, string.Empty);

                    //parker zhou : for email
                    BEGDC.CC.BL.Email.IEmail email = AppContainer.Instance[BEGDC.CC.BL.Common.ServiceConst.EmailService] as BEGDC.CC.BL.Email.IEmail;
                    email.Send(flowinstance.FlowID, "OCV_ReportApprove");
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }
        #endregion

        /// <summary>
        /// IBGHeader is ReportTo
        /// </summary>
        private void IBGHeaderIsReportTo(long flowID)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    //if IBGHeader is ReportTo
                    FlowInstance instance = this.GetFlowInstance.QueryFlowInstance(session, flowID);
                    if (instance.Application.NeedEVPApproval)
                    {
                        FlowMember IBGHeader = this.GetFlowInstance.GetFlowMemberByAppStep(session, instance.Application.Id, WorkTransition.OCV_SSMEEVPApproval, FlowTypes.OCV);
                        if (IBGHeader != null && IBGHeader.Employee != null && instance.Application.RequesterNo.ReportTo != null)
                        {
                            if (IBGHeader.Employee.Id.Equals(instance.Application.RequesterNo.ReportTo.Id))
                            {
                                this.GetFlowInstance.Perform(session, flowID, BEGDC.CC.BL.Workflow.OCVTransitionList.Approve, WorkTransition.OCV_SSMEEVPApproval, IBGHeader, string.Empty);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// CostCenter header equals applicant or reportto or lv4Approver, then header need to automatically approve
        /// </summary>
        /// <param name="instance">FlowInstance</param>
        private void CostCenterAutomaticallyApprove(BEGDC.CC.Entity.FlowInstance instance)
        {
            using (ISession session = _sessionManager.OpenSession())
            {
                try
                {
                    Application app = instance.Application;

                    FlowMember costCenterHeader = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_CostCenterHeadApproval, FlowTypes.OCV);
                    FlowMember lv4ApproverMember = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_Lv4Approval, FlowTypes.OCV);

                    if (costCenterHeader != null && lv4ApproverMember != null && instance.Application.IsSSME)
                    {
                        Employee costcenter = costCenterHeader.Employee;
                        Employee applicant = app.RequesterNo;
                        Employee reportto = applicant.ReportTo;
                        Employee lv4Approver = lv4ApproverMember.Employee;

                        if ((costcenter != null && costcenter.Id.Equals(applicant.Id)) || (reportto != null && costcenter.Id.Equals(reportto.Id)) || (lv4Approver != null && costcenter.Id.Equals(lv4Approver.Id)))
                        {
                            this.GetFlowInstance.Perform(session, instance.FlowID, BEGDC.CC.BL.Workflow.OCVTransitionList.Approve, WorkTransition.OCV_CostCenterHeadApproval, costCenterHeader, string.Empty);

                            this.Lv4ApproverAutomaticallyApprove(session, instance, app);
                        }
                    }
                }
                catch (Exception ex)
                {
                    CCS.Utility.LogAccess.WriteErrLog(ex.StackTrace, ex.Message); throw ex;
                }
                finally
                {
                    session.Close();
                }
            }
        }

        /// <summary>
        /// Automatically approved requirements
        /// Don't need next LvApprover
        /// Lv4Approver equals ReportTo
        /// </summary>
        /// <param name="session">ISession</param>
        /// <param name="flowinstance">Get FlowID</param>
        /// <param name="app">Appliaction</param>
        private void Lv4ApproverAutomaticallyApprove(ISession session, BEGDC.CC.Entity.FlowInstance instance, Application app)
        {
            BEGDC.CC.BL.Common.Query.IQuery queryService = AppContainer.Instance[ServiceConst.QueryService] as BEGDC.CC.BL.Common.Query.IQuery;

            FlowMember lv4ApproverMember = this.GetFlowInstance.GetFlowMemberByAppStep(session, app.Id, WorkTransition.OCV_Lv4Approval, FlowTypes.OCV);

            if (!queryService.IsNeedNextLvApprover(instance.FlowID, WorkTransition.OCV_Lv4Approval) && lv4ApproverMember != null)
            {
                Employee lv4Approver = lv4ApproverMember.Employee;
                Employee reportto = app.RequesterNo.ReportTo;

                if (lv4Approver != null && reportto != null && reportto.Id.Equals(lv4Approver.Id))
                {
                    this.GetFlowInstance.Perform(session, instance.FlowID, BEGDC.CC.BL.Workflow.OCVTransitionList.Approve, WorkTransition.OCV_Lv4Approval, lv4ApproverMember, string.Empty);
                }
            }
        }
    }
}
